/*!
 * \file xml_trans.c
 *
 * \brief 交易通信
 *
 * All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.
 *
 * \version 1.0
 * \author songbb
 * \date 2016/08/08
 *
 */

#include <iconv2utf8.h>
#include <frxml_parse.h>
#include "conntrack.h"
#include "frct_comm.h"
#include "frreport_comm.h"

#include "xml_core.h"
#include "xml_comm.h"
#include "xml_trans.h"

FR_STATIC int xml_get_xml_string(L7_xml_packet *p_st_xml_packet
                                , unsigned int ui_len
                                , char **pp_out)
{
    char *p_outtmp = NULL;
    char *p_buff_out = NULL;
    unsigned int ui_out_len = 0;
    char *p_encoding = NULL;

    if (ui_len > 0)
    {
        if ((p_outtmp = (char *) frmalloc((ui_len + 1) * sizeof(char))) == NULL)
        {
            XML_MALLOCK_ERR;
            goto error;
        }
        if (bytebuff_get_bytes(p_st_xml_packet->p_st_packet, p_outtmp, ui_len) != FR_SUCC)
            goto error;
        p_outtmp[ui_len] = '\0';

        if (frxml_get_encoding(p_outtmp, ui_len, &p_encoding) != FR_SUCC)
            goto error;
        XML_PRINT_DBG("encoding:[%s]\n", p_encoding);

        if (iconv_to_utf8(p_outtmp, ui_len, p_encoding, &p_buff_out, &ui_out_len) == FR_SUCC)
            goto success;
        xml_free((void **) &p_buff_out);

        if ((p_buff_out = (char *) frmalloc((ui_len + 1) * sizeof(char))) == NULL)
        {
            XML_MALLOCK_ERR;
            goto error;
        }
        memcpy(p_buff_out, p_outtmp, ui_len);
        p_buff_out[ui_len] = '\0';
    }

success:
    xml_free((void **) &p_encoding);
    xml_free((void **) &p_outtmp);
    *pp_out = p_buff_out;
    return FR_SUCC;
error:
    xml_free((void **) &p_encoding);
    xml_free((void **) &p_outtmp);
    xml_free((void **) &p_buff_out);
    return FR_FAIL;
}

int xml_req(Conntrack *p_st_conn
            , L7_xml_packet *p_st_xml_packet
            , Frhash_header *p_st_hash_report)
{
    XML_PRINT_INFO("xml_req...\n");
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_xml_private *p_st_session_private = (L7session_xml_private *) frct_get_session_private(p_st_session);
    char *p_xml_string = NULL;
    Frreport_body_data *p_st_body = NULL;

    if (bytebuff_skip(p_st_xml_packet->p_st_packet, p_st_xml_packet->ui_header_len) != FR_SUCC)
        goto error;

    if (xml_get_xml_string(p_st_xml_packet, (unsigned int) bytebuff_remaining(p_st_xml_packet->p_st_packet),
                            &p_xml_string) != FR_SUCC)
        goto error;
    XML_PRINT_INFO("xml_string:[%s]\n", p_xml_string);

    xml_init_stmt(p_st_session_private->p_st_xml_stmt);

    // 新建上报数据结构体
    if ((p_st_body = frreport_body_new_l7(p_st_conn)) == NULL)
        goto error;

    if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_TRANS_TITLE, "XML Request") != FR_SUCC)
        goto error;
    if (p_xml_string)
    {
        if (frreport_body_l7_add_str(p_st_body, APM_XML_REPORT_REQ_MESSAGE_DATA, p_xml_string) != FR_SUCC)
            goto error;
    }

    // 上报数据
    if (xml_report_msg_data_req(p_st_conn, p_st_xml_packet, p_st_body, p_st_hash_report) != FR_SUCC)
        goto error;

    xml_free((void **) &p_xml_string);
    return FR_SUCC;
error:
    xml_free((void **) &p_xml_string);
    frreport_body_free(&p_st_body);
    return FR_FAIL;
}

int xml_resp(Conntrack *p_st_conn
                , L7_xml_packet *p_st_xml_packet
                , Frhash_header *p_st_hash_report)
{
    XML_PRINT_INFO("xml_resp...\n");
    char *p_xml_string = NULL;
    Frreport_body_data *p_st_body = NULL;

    if (bytebuff_skip(p_st_xml_packet->p_st_packet, p_st_xml_packet->ui_header_len) != FR_SUCC)
        goto error;

    if (xml_get_xml_string(p_st_xml_packet, (unsigned int) bytebuff_remaining(p_st_xml_packet->p_st_packet),
                            &p_xml_string) != FR_SUCC)
        goto error;
    XML_PRINT_INFO("xml_string:[%s]\n", p_xml_string);

    // 新建上报数据结构体
    if ((p_st_body = frreport_body_new_l7(p_st_conn)) == NULL)
        goto error;

    if (p_xml_string)
    {
        if (frreport_body_l7_add_str(p_st_body, APM_XML_REPORT_RESP_MESSAGE_DATA, p_xml_string) != FR_SUCC)
            goto error;
    }

    if (frreport_body_l7_add_int(p_st_body, APM_REPORT_KEY_RESP_CODE, 0) != FR_SUCC)
        goto error;

    // 上报数据
    if (xml_report_msg_data_resp(p_st_conn, p_st_xml_packet, p_st_body, p_st_hash_report) != FR_SUCC)
        goto error;

    xml_free((void **) &p_xml_string);

    return FR_SUCC;
error:
    xml_free((void **) &p_xml_string);
    frreport_body_free(&p_st_body);
    return FR_FAIL;
}
